package hjt.com.module_design_pattern.pattern.proxy;

import android.os.Bundle;

import com.tong.lib.base.BaseActivity;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import hjt.com.module_design_pattern.R;

public class ProxyActivity extends BaseActivity {


    @Override
    protected int getLayoutResID() {
        return R.layout.design_activity_proxy;
    }

    @Override
    protected void init(Bundle savedInstanceState) {
        //静态代理类
        XiaoMing xiaoMing = new XiaoMing();
        Lawer lawer = new Lawer(xiaoMing);
        lawer.submit();
        lawer.defend();
        lawer.finish();

        //动态代理
        XiaoMing xiaoMing1 = new XiaoMing();
        //构造一个动态代理
        DynamicProxy dynamicProxy = new DynamicProxy(xiaoMing1);
        //获取被代理类xiaoming的ClassLoader
        ClassLoader classLoader = xiaoMing1.getClass().getClassLoader();
        //动态构建一个代理类
        ILawsuit layer2 = (ILawsuit) Proxy.newProxyInstance(classLoader, new Class[]{ILawsuit.class}, dynamicProxy);
        layer2.submit();
        layer2.defend();
        layer2.finish();

        //动态代理可以通过一个代理类来管理N多个被代理类，其实质是对代理者和被代理者进行解耦，使两者没有直接的耦合关系；
        //相对而言，静态代理则只能为   给定接口   下的实现类做代理，如果接口不同就需要重新定义不同的代理类

        ILawsuit iLawsuit = getProxy(ILawsuit.class);
        iLawsuit.submit();
        iLawsuit.defend();
        iLawsuit.finish();
    }

    @Override
    protected void initEvent() {

    }

    private <T> T getProxy(final Class<T> cls) {
        return (T) Proxy.newProxyInstance(cls.getClassLoader(), new Class[]{cls}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return getAnnotationValue(method);
            }
        });
    }

    private String getAnnotationValue(Method method) {
        if (method.isAnnotationPresent(DefaltValue.class)) {
            method.setAccessible(true);
            DefaltValue annotation = method.getAnnotation(DefaltValue.class);
            show(annotation.value());
            return annotation.value();
        }
        return "";
    }

}
